/**
 * 讯飞语音合成（TTS）服务
 * 使用 WebAPI 实时合成语音
 */

import Sound from 'react-native-sound';
import CryptoJS from 'crypto-js';
import { IFLYTEK_APP_ID, IFLYTEK_API_KEY, IFLYTEK_API_SECRET } from '@env';

class IflytekTtsService {
  constructor() {
    this.ws = null;
    this.audioChunks = [];
    this.currentSound = null;
    this.tempAudioPath = null;
  }

  /**
   * 生成鉴权URL
   * 参考文档：https://www.xfyun.cn/doc/tts/online_tts/API.html#接口鉴权
   */
  getAuthUrl() {
    const host = 'tts-api.xfyun.cn';
    const path = '/v2/tts';
    const date = new Date().toUTCString();

    // 1. 构建签名原文（注意格式：host、date、request-line用换行符分隔）
    const signatureOrigin = `host: ${host}\ndate: ${date}\nGET ${path} HTTP/1.1`;

    // 2. 使用 HMAC-SHA256 加密（文档要求使用SHA256）
    const signature = CryptoJS.HmacSHA256(signatureOrigin, IFLYTEK_API_SECRET);
    const signatureBase64 = CryptoJS.enc.Base64.stringify(signature);

    // 3. 构建authorization参数
    const authorizationOrigin = `api_key="${IFLYTEK_API_KEY}", algorithm="hmac-sha256", headers="host date request-line", signature="${signatureBase64}"`;
    const authorization = CryptoJS.enc.Base64.stringify(
      CryptoJS.enc.Utf8.parse(authorizationOrigin),
    );

    // 4. 构建完整的WebSocket URL
    const url = `wss://${host}${path}?authorization=${encodeURIComponent(
      authorization,
    )}&date=${encodeURIComponent(date)}&host=${encodeURIComponent(host)}`;

    return url;
  }

  /**
   * 合成语音
   * @param {string} text - 要合成的文本
   * @param {Object} options - 合成参数
   * @returns {Promise<string>} 音频文件路径
   */
  async synthesize(text, options = {}) {
    return new Promise((resolve, reject) => {
      try {
        const url = this.getAuthUrl();

        this.ws = new WebSocket(url);
        this.audioChunks = [];

        this.ws.onopen = () => {
          // 构建合成参数
          const params = {
            common: {
              app_id: IFLYTEK_APP_ID,
            },
            business: {
              aue: 'lame', // 音频编码：lame(mp3)
              auf: 'audio/L16;rate=16000', // 音频采样率
              vcn: options.voiceName || 'xiaoyan', // 发音人：xiaoyan(温柔女声), aisjiuxu(情感男声), aisxping(温暖女声)
              speed: options.speed || 50, // 语速：0-100，默认50
              volume: options.volume || 50, // 音量：0-100，默认50
              pitch: options.pitch || 50, // 音高：0-100，默认50
              bgs: 0, // 背景音乐：0(无)
              tte: 'UTF8', // 文本编码
            },
            data: {
              status: 2, // 数据状态：2(一次传完)
              text: CryptoJS.enc.Base64.stringify(
                CryptoJS.enc.Utf8.parse(text),
              ), // base64编码的文本
            },
          };

          this.ws.send(JSON.stringify(params));
        };

        this.ws.onmessage = event => {
          try {
            const response = JSON.parse(event.data);

            if (response.code !== 0) {
              reject(new Error(response.message));
              return;
            }
            // 接收音频数据
            if (response.data && response.data.audio) {
              const audioData = response.data.audio; // base64格式的音频
              this.audioChunks.push(audioData);
            }

            // 合成完成
            if (response.data && response.data.status === 2) {
              this.ws.close();

              // 合并所有音频片段
              const completeAudio = this.audioChunks.join('');
              resolve(completeAudio);
            }
          } catch (error) {
            reject(error);
          }
        };

        this.ws.onerror = error => {
          reject(error);
        };

        this.ws.onclose = () => {};
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 播放合成的语音
   * @param {string} base64Audio - base64格式的音频数据
   * @returns {Promise<void>}
   */
  async play(base64Audio) {
    return new Promise((resolve, reject) => {
      try {
        // 将base64转为音频文件并播放
        const RNFS = require('react-native-fs');
        const audioPath = `${RNFS.CachesDirectoryPath}/tts_${Date.now()}.mp3`;

        // 写入文件
        RNFS.writeFile(audioPath, base64Audio, 'base64')
          .then(() => {
            // 播放音频
            this.currentSound = new Sound(audioPath, '', error => {
              if (error) {
                reject(error);
                return;
              }

              this.currentSound.play(success => {
                if (success) {
                } else {
                }

                // 释放资源
                this.currentSound.release();
                this.currentSound = null;

                // 删除临时文件
                RNFS.unlink(audioPath).catch(() => {});

                resolve();
              });
            });
          })
          .catch(error => {
            reject(error);
          });
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 合成并播放（一步到位）
   * @param {string} text - 要合成的文本
   * @param {Object} options - 合成参数
   */
  async speak(text, options = {}) {
    try {
      const audioData = await this.synthesize(text, options);
      await this.play(audioData);
    } catch (error) {
      throw error;
    }
  }

  /**
   * 停止播放
   */
  stop() {
    return new Promise(resolve => {
      if (this.currentSound) {
        try {
          this.currentSound.stop(() => {
            if (this.currentSound) {
              this.currentSound.release();
              this.currentSound = null;
            }
            // WebSocket 也需要关闭
            if (this.ws) {
              this.ws.close();
              this.ws = null;
            }
            resolve();
          });
        } catch (error) {
          // 出错也要清理
          if (this.currentSound) {
            this.currentSound = null;
          }
          if (this.ws) {
            this.ws.close();
            this.ws = null;
          }
          resolve();
        }
      } else {
        // 没有音频播放，但可能有 WebSocket 连接
        if (this.ws) {
          this.ws.close();
          this.ws = null;
        }
        resolve();
      }
    });
  }

  /**
   * 清理资源
   */
  async cleanup() {
    await this.stop();
    this.audioChunks = [];
  }
}

export default new IflytekTtsService();
